#include "cnscene.h"
#include "cnconstantitem.h"
#include "cnpointitem.h"
#include "cnarrowitem.h"
#include "cnadditem.h"
#include "cnItemcommon.h"
#include "icnitemcommon.h"
#include <QPen>
#include <QPainter>
#include <QMimeData>
#include <QPixmap>
#include <QCursor>
#include <QDebug>
#include <QGraphicsLineItem>
#include <QPen>
#include <QGraphicsSceneDragDropEvent>
#include <QGraphicsRectItem>
#include <QGraphicsItem>
#include <QJsonObject>
#include <QJsonArray>
#include <QGraphicsItem>
#include <QJsonDocument>
#include <QFile>

CNScene::CNScene(QObject *parent)
    : QGraphicsScene(parent), m_pLineItem(nullptr)
{
    setSceneRect(-100, -100, 200, 200);
}

void CNScene::drawBackground(QPainter *painter, const QRectF &rect)
{
    QGraphicsScene::drawBackground(painter,rect);

    Q_UNUSED(rect);

    QPen pen;

    qreal left=rect.left();
    qreal right=rect.right();
    qreal top=rect.top();
    qreal bottom=rect.bottom();

    //边界值调整
    left = (left/100)*100;
    right = (right/100)*100;
    top = (top/100)*100;
    bottom = (bottom/100)*100;

    pen.setColor(QColor("lightgrey"));
    pen.setWidth(0);
    pen.setStyle(Qt::DashLine);
    painter->setPen(pen);

    //绘制横线
    //绘制Y轴正半轴
    for(int i=0;i>=top;i-=100)
    {
        painter->drawLine(left,i,right,i);
    }
    //绘制Y轴负半轴
    for(int i=0;i<=bottom;i+=100)
    {
        painter->drawLine(left,i,right,i);
    }

    //绘制竖线
    //绘制X轴正半轴
    for(int i=0;i<=right;i+=100)
    {
        painter->drawLine(i,top,i,bottom);
    }
    //绘制X轴负半轴
    for(int i=0;i>=left;i-=100)
    {
        painter->drawLine(i,top,i,bottom);
    }
}

void CNScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    const QMimeData *mimeData = event->mimeData();

    QString type = mimeData->text();
    if ("c" == type.toLower())
    {
        CNConstantItem* item = new CNConstantItem();
        item->setName("C");
        //item->setCursor(QCursor(Qt::ArrowCursor));
        addItem(item);
        item->setPos(event->scenePos() + item->boundingRect().center() + QPoint(18, 18));
    }
    else if ("add" == type.toLower())
    {
        CNAddItem *item = new CNAddItem();
        item->setName("ADD");
        item->setCursor(QCursor(Qt::ArrowCursor));

        addItem(item);
        item->setPos(event->scenePos() + item->boundingRect().center() + QPoint(18, 18));
    }

    QGraphicsScene::dropEvent(event);
}

void CNScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() != Qt::LeftButton) {
        return;
    }

    QGraphicsItem *item = itemAt(event->scenePos(), QTransform());
    if(!item) {
        item = itemAt(event->scenePos() + QPointF(0.5, 0.5), QTransform());
    }

    if(item) {
        if (CN::DiagramType::Pin == item->type())
        {
            m_pLineItem = new QGraphicsLineItem(QLineF(item->mapToScene(item->boundingRect().center()), event->scenePos()));
            m_pLineItem->setCursor(QCursor(Qt::CrossCursor));
            m_pLineItem->setZValue(-1);
            m_pLineItem->setPen(QPen(QColor("black"), 2));
            addItem(m_pLineItem);
        }
    }

    QGraphicsScene::mousePressEvent(event);
}

void CNScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_pLineItem) {
        QLineF newLine(m_pLineItem->line().p1(), event->scenePos());
        m_pLineItem->setLine(newLine);
    }
    else {
        QGraphicsScene::mouseMoveEvent(event);
    }
}

void CNScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_pLineItem) {
        QGraphicsItem* item = itemAt(event->scenePos(), QTransform());

        if (item && CN::DiagramType::Pin == item->type()) {
            QLineF newLine(m_pLineItem->line().p1(), event->scenePos());
            delete m_pLineItem;
            m_pLineItem = nullptr;

            CNPointItem* startItem = qgraphicsitem_cast<CNPointItem*>(itemAt(newLine.p1(), QTransform()));
            CNPointItem* endItem = qgraphicsitem_cast<CNPointItem*>(itemAt(newLine.p2(), QTransform()));

            CNBaseItem* startParentItem = qgraphicsitem_cast<CNBaseItem*>(startItem->parentItem());
            CNBaseItem* endParentItem = qgraphicsitem_cast<CNBaseItem*>(endItem->parentItem());

            if (startParentItem == endParentItem)
            {
                return;
            }

            CNArrowItem* arrowItem = new CNArrowItem(startItem, endItem);
            arrowItem->setZValue(-1);
            addItem(arrowItem);

            startParentItem->addArrow(arrowItem);
            endParentItem->addArrow(arrowItem);

            arrowItem->updatePosition();
        }
        else {
            delete m_pLineItem;
            m_pLineItem = nullptr;
        }
    }
    else {
        QGraphicsScene::mouseReleaseEvent(event);
    }
}

void CNScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{

}

QJsonObject CNScene::serializeScene()
{
    QJsonObject sceneObj;
    QJsonArray itemsArray;
    int num = items().size();
    foreach(QGraphicsItem * item1, items()) {
        CNItemCommon* item = static_cast<CNItemCommon*>(item1);
        QJsonObject itemObj;
        
        ICNItemCommon* it = item;
        itemObj = it->serialize();

        //else if (item->type() == CN::DiagramType::Sum) {
        //    CNItemCommon* it = static_cast<CNItemCommon*>(item);
        //    itemObj = it->serialize();
        //}
        //else if (item->type() == CN::DiagramType::Pin) {
        //    CNItemCommon* it = static_cast<CNItemCommon*>(item);
        //    itemObj = it->serialize();
        //} else if()
        //else {  // 先不绘制线
        //    continue;
        //}
        itemsArray.append(itemObj);
    }
    sceneObj["items"] = itemsArray;
    return sceneObj;
}


void CNScene::onSaveFile()
{
    QJsonObject sceneObj = serializeScene();
    QJsonDocument doc(sceneObj);
    QFile file("D:\\aaaa.json");
    if (file.open(QIODevice::WriteOnly)) {
        file.write(doc.toJson());
        file.close();
    }
}